package Task25;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public final class Factory{
        
        private static Map<String,Constructor<?>> mapCommandClasses;
        private static Map<String,modelInterface>Instances;
        private static boolean createMap = false;
        private static String operation;
        
        //method for create the map, performed once
        public static void form_Map() throws Exception, SecurityException, IllegalAccessException, NoSuchFieldException{
                if(!createMap){
                mapCommandClasses = new HashMap<String,Constructor<?>>();
                Instances = new HashMap<String,modelInterface>();
                for (Class<?> subclass : new Model().getClass().getClasses()) { 
                        Constructor<?> constructor = subclass.getDeclaredConstructor(Model.class);
                        constructor.setAccessible(true);
                        String Key = (String)constructor.newInstance(new Model()).getClass().getDeclaredField("key").get(null);
                        mapCommandClasses.put(Key,constructor);
                        Instances.put(Key,null);
                }
                createMap=true;
                }
        }
        //realization method for getting the new instance, but previously check him exist (singleton)
        public static modelInterface getInstance(String[] args) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
                String command = args[0];
                operation = command;
                if (Instances.get(command)==null){
                modelInterface instance = (modelInterface) mapCommandClasses.
                                get(command).newInstance(new Model());
                Instances.put(command,instance);
                return instance;
                }
                else return Instances.get(command);
        }
        
        public static String getCommnad(){ return operation;}
}
